package com.niiwoo.civet.trade.service.local.newRefund.refundDeal.core;

import com.niiwoo.civet.base.enums.OrderTradeSourceEnum;
import com.niiwoo.civet.base.enums.RefundTypeEnum;
import com.niiwoo.civet.trade.dao.entity.Project;
import com.niiwoo.civet.trade.dao.entity.ProjectBorrowerSummary;
import com.niiwoo.civet.trade.dao.entity.RefundOrder;
import com.niiwoo.civet.trade.dao.mapper.RefundOrderMapperExt;
import com.niiwoo.civet.trade.dto.newRefund.RefundStateDTO;
import com.niiwoo.civet.trade.enums.RefundOptTypeEnum;
import com.niiwoo.civet.trade.enums.RefundTradeTypeEnum;
import com.niiwoo.civet.trade.enums.RepayStatusEnum;
import com.niiwoo.tripod.provider.exception.BizException;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;

@Service
@Slf4j
public class RefundService {

    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;

    @Autowired
    private RefundOrderMapperExt refundOrderMapperExt;


    /**
     * 还款核心流程
     * @param projectId
     * @param orderTradeSourceEnum
     * @param refundTypeEnum
     * @return
     */
    @Transactional(isolation = Isolation.READ_COMMITTED)
    @Deprecated
    public RefundOrder refund(long projectId, OrderTradeSourceEnum orderTradeSourceEnum, RefundTypeEnum refundTypeEnum){
        log.info("" + projectId);
        log.info(orderTradeSourceEnum.name());
        log.info(refundTypeEnum.name());
        return null;
    }

    /**
     * 还款检查
     * @param summary
     * @param refundTypeEnum
     */
    public void check(ProjectBorrowerSummary summary, RefundTypeEnum refundTypeEnum, Date currentDate, Byte deadLineUnit){
        if(RefundTypeEnum.IMMEDIATELY.equals(refundTypeEnum)){
            Date maxDate = new DateTime(currentDate).plusMonths(1).toDate();
            if (!maxDate.after(summary.getRefundDate()) && Byte.valueOf("1").equals(deadLineUnit)){
                throw new BizException("TRD30004");// 不可提前一个月操作正常还款
            }
        }else if(RefundTypeEnum.OVERDEPT.equals(refundTypeEnum)){
            if(RepayStatusEnum.BADLOANS.getCode().equals(summary.getRepayStatus())){
                throw new BizException("TRD90015");// 标的已坏账，不能提前结清
            }
        }
        this.check(summary.getProjectId());
    }

    /**
     * 代还/垫付校验
     * @param projectId
     */
    public void check(Long projectId){
        int count = refundOrderMapperExt.selectInProgressOrderCount(projectId);
        if(count > 0){
            log.error("标的还款失败，有一笔还款订单正在处理，projectId=" + projectId);
            throw new BizException("TRD_800001");// 您好，您的还款银行正在处理，请勿重复提交
        }
    }

    /**
     * 创建还款订单 类外部不要使用此方法
     * @param refundTypeEnum
     * @param refundTradeTypeEnum
     * @param orderTradeSourceEnum
     * @param refundStateDTO
     * @param couldRefundStateDTO
     * @param project
     * @param sourceAccountId
     * @param sourcePlatformUserNo
     * @param sourceUserId
     * @param currentDate
     * @param repayStatus
     * @param compareDate
     * @param specifiedAmount
     * @param refundOptTypeEnum
     * @param periods
     * @param orgRequestNo
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public RefundOrder createRefundOrder(RefundTypeEnum refundTypeEnum, RefundTradeTypeEnum refundTradeTypeEnum, OrderTradeSourceEnum orderTradeSourceEnum,
                                         RefundStateDTO refundStateDTO, RefundStateDTO couldRefundStateDTO, Project project, Long sourceAccountId,
                                         String sourcePlatformUserNo, String sourceUserId, Date currentDate, Byte repayStatus, Date compareDate,
                                         BigDecimal specifiedAmount, RefundOptTypeEnum refundOptTypeEnum,String periods,String orgRequestNo){
        RefundOrder refundOrder = new RefundOrder();
        refundOrder.setId(this.snowflakeIdWorker.nextId());
        refundOrder.setRefundType(refundTypeEnum.getRefundType());
        refundOrder.setTradeType(refundTradeTypeEnum.getTradeType());
        refundOrder.setPeriods(periods);
        refundOrder.setOrgRequestNo(orgRequestNo);
        refundOrder.setTradeSource(orderTradeSourceEnum.getTradeSource());
        refundOrder.setSourceAccountId(sourceAccountId);
        refundOrder.setSourcePlatformUserNo(sourcePlatformUserNo);
        refundOrder.setSourceUserId(sourceUserId);
        refundOrder.setBorrowAccountId(project.getBorrowAccountId());
        refundOrder.setBorrowPlatformUserNo(project.getBorrowPlatformUserNo());
        refundOrder.setBorrowUserId(project.getBorrowUserId());
        refundOrder.setProjectId(project.getProjectId());
        refundOrder.setOrgId(project.getOrgId());
        // 可还
        refundOrder.setAmount(couldRefundStateDTO.getAmount());
        refundOrder.setCapital(couldRefundStateDTO.getCapital());
        refundOrder.setInterest(couldRefundStateDTO.getInterest());
        refundOrder.setPenaltyFee(couldRefundStateDTO.getPenaltyFee());
        refundOrder.setManageFee(couldRefundStateDTO.getManageFee());
        refundOrder.setGuaranteeFee(couldRefundStateDTO.getGuaranteeFee());
        refundOrder.setConsultingFee(couldRefundStateDTO.getConsultingFee());
        // 应还
        refundOrder.setRefundingAmount(refundStateDTO.getAmount());
        refundOrder.setRefundingCapital(refundStateDTO.getCapital());
        refundOrder.setRefundingInterest(refundStateDTO.getInterest());
        refundOrder.setRefundingPenaltyFee(refundStateDTO.getPenaltyFee());
        refundOrder.setRefundingManageFee(refundStateDTO.getManageFee());
        refundOrder.setRefundingGuaranteeFee(refundStateDTO.getGuaranteeFee());
        refundOrder.setRefundingConsultingFee(refundStateDTO.getConsultingFee());

        refundOrder.setCurrentDate(currentDate);
        refundOrder.setOptType(refundOptTypeEnum.getOptType());
        refundOrder.setRepayStatus(repayStatus);
        refundOrder.setCompareDate(compareDate);
        if(null != specifiedAmount){
            refundOrder.setSpecifiedAmount(specifiedAmount);
        }
        refundOrder.setCreateTime(new Date());
        refundOrder.setUpdateTime(new Date());
        refundOrderMapperExt.insertSelective(refundOrder);
        return refundOrder;
    }

}
